﻿//
// App.xaml.cpp
// Implementation of the App class.
//

#include "pch.h"
#include "App.xaml.h"
#include "MainPage.xaml.h"

using namespace Coding4Fun::Maelstrom::GameConsole;

using namespace Platform;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Storage;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;

using namespace Windows::Graphics::Display;

using namespace DirectX;
using namespace concurrency;

/// <summary>
/// Initializes the singleton application object.  This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
	InitializeComponent();
	Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
	UnhandledException += ref new UnhandledExceptionEventHandler(this, &App::OnUnhandledException);
}

/// <summary>
/// Invoked when the application is launched normally by the end user.  Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
void App::OnLaunched(LaunchActivatedEventArgs^ args)
{
	m_mainPage = ref new MainPage();

	Window::Current->Content = m_mainPage;
	Window::Current->Activate();

	m_renderer = ref new GameRenderer();
	m_renderer->Initialize(Window::Current->CoreWindow, m_mainPage->GetSwapChainBackgroundPanel(), DisplayProperties::LogicalDpi);

	m_gameEngine = ref new GameEngine();

	m_mainPage->InitializeInputs(m_gameEngine);

	m_onRenderingEventToken = CompositionTarget::Rendering::add(ref new EventHandler<Object^>(this, &App::OnRendering));

	create_task([this]()
	{
		m_gameEngine->Initialize(m_renderer, m_mainPage);
		return m_renderer->CreateGameDeviceResourcesAsync(m_gameEngine);
	}).then([this]()
	{
		m_renderer->CreateGameDeviceResourcesFinalize();
	}, task_continuation_context::use_current()
	).then([this](task <void> t)
	{
		try
		{
			t.get();
			//m_mainPage->SetOutputText("All done");
			m_gameEngine->SetGameState(Coding4Fun::Maelstrom::Common::GameState::WaitingRoom);
		}
		catch(Exception^ ex)
		{
			m_mainPage->SetOutputText(ex->Message);
			OutputDebugString(ex->Message->Data());
		}
	});

}

void App::OnRendering( _In_ Object^,  _In_ Object^ )
{
	m_gameEngine->GameTick();
	m_renderer->Render();
}

/// <summary>
/// Invoked when the application is being suspended.
/// </summary>
/// <param name="sender">Details about the origin of the event.</param>
/// <param name="args">Details about the suspending event.</param>
void App::OnSuspending(Object^ sender, SuspendingEventArgs^ args)
{
	(void) sender; // Unused parameter.
	(void) args; // Unused parameter.

	//m_mainPage->SaveInternalState(ApplicationData::Current->LocalSettings->Values);
}

void App::OnUnhandledException(Object^ sender, UnhandledExceptionEventArgs^ args)
{
	m_mainPage->SetOutputText(args->Message);
	OutputDebugString(args->Message->Data());
}
